package indi.kider.server.employee.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import indi.kider.common.constant.AppUserType;
import indi.kider.common.constant.StatusCons;
import indi.kider.common.constant.TenantTypeCons;
import indi.kider.common.model.apabus.Rent;
import indi.kider.common.model.apartment.DevLock;
import indi.kider.common.model.apartment.DevLockCard;
import indi.kider.common.model.apartment.DevLockFingerPrint;
import indi.kider.common.model.apartment.DevLockPassword;
import indi.kider.common.model.employee.Employee;
import indi.kider.common.model.employee.Tenant;
import indi.kider.common.model.employee.TenantQuery;
import indi.kider.common.model.woniubus.DevSensetimeUpload;
import indi.kider.common.util.HttpClientUtils;
import indi.kider.server.apabus.mapper.RentMapper;
import indi.kider.server.apartment.mapper.*;
import indi.kider.server.employee.mapper.TenantMapper;
import indi.kider.server.employee.service.related.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.vankid.common.model.base.CommonResponse;
import pers.vankid.common.model.base.CoreException;
import pers.vankid.common.utils.page.PageRequest;
import pers.vankid.common.utils.page.PageResponse;
import pers.vankid.common.utils.page.PageUtil;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by shixj on 2018/4/26.
 */
@Slf4j
@Service
public class TenantServiceImpl implements TenantService {
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private UserService  userService;
    @Autowired
    private SmsService   smsService;
    @Autowired
    private DevLockPasswordMapper devLockPasswordMapper;
    @Autowired
    private DevLockCardMapper devLockCardMapper;
    @Autowired
    private DevLockFingerprintMapper devLockFingerprintMapper;
    @Autowired
    private RentMapper rentMapper;
    @Autowired
    private DevLockMapper devLockMapper;

    /**
     * 根据id获取
     *
     * @param id
     * @return
     */
    @Override
    public Tenant getTenantById(Long id) {
        return tenantMapper.selectByPrimaryKey(id);
    }

    /**
     * 获取分页查询
     *
     * @param request
     * @return
     */
    @Override
    public PageResponse<List<Tenant>> getTenantPages(PageRequest<Tenant> request) {
        PageUtil.start(request);
        return PageUtil.getPageResponse(tenantMapper.select(request.getQuery()));
    }

    /**
     * 不分页查询
     *
     * @param tenant
     * @return
     */
    @Override
    public List<Tenant> getTenants(Tenant tenant) {
        return tenantMapper.select(tenant);
    }

    /**
     * 新增
     * @param tenant
     * @return
     */
    @Override
    public Tenant add(Tenant tenant) {
        if (tenant != null) {
            if (tenant.getId() == null || tenant.getId().equals(0L)) {
                //存在的手机号=======
                String phone = tenant.getPhone();
                Tenant temp = new Tenant();
                temp.setPhone(phone);
                temp.setState(StatusCons.VALID);
                List<Tenant> tenants = tenantMapper.select(temp);
                if (tenants.size() == 0) {
                    tenant.setId(null);
                    tenantMapper.insert(tenant);
                    userService.insert(tenant.getPhone(), AppUserType.TENANT);
                }else{
                    Tenant update = tenantMapper.selectOne(temp);
                    tenant.setId(update.getId());
                    tenantMapper.updateByPrimaryKeySelective(tenant);
                    userService.modify(tenants.get(0).getPhone(), tenant.getPhone());
                }
            }
        }
        return tenant;
    }


    /**
     * 更新
     * @param tenant
     * @return
     */
    @Override
//    public Tenant modify(Tenant tenant) throws Exception{
//        if (tenant != null && tenant.getId() != null && tenant.getId() > 0L) {
//            String phone = tenant.getPhone();
//            Tenant temp = new Tenant();
//            temp.setPhone(phone);
//            temp.setState(StatusCons.VALID);
//            Tenant tenant1 = tenantMapper.selectOne(temp);
//            if(tenant1==null){
//                tenantMapper.updateByPrimaryKeySelective(tenant);
//                userService.modify(tenant1.getPhone(), tenant.getPhone());
//            }else {
//                Tenant update = tenantMapper.selectOne(temp);
//                if(update.getId() .equals(tenant.getId()) ){
//                    tenantMapper.updateByPrimaryKeySelective(tenant);
//                    userService.modify(tenant1.getPhone(), tenant.getPhone());
//                }else{
//                    throw new Exception("手机号"+phone+"已存在！");
//                }
//            }
//        }
//        return tenant;
//    }
    public Tenant modify(Tenant tenant) throws Exception{
        if (tenant != null && tenant.getId() != null && tenant.getId() > 0L) {
            Tenant tenant1 = tenantMapper.selectByPrimaryKey(tenant.getId());
            String oldPhone = tenant1.getPhone();
            String newPhone = tenant.getPhone();
            Tenant temp = new Tenant();
            temp.setPhone(newPhone);
            temp.setState(StatusCons.VALID);
            Tenant tenant2 = tenantMapper.selectOne(temp);
            if(tenant2==null){
                tenantMapper.updateByPrimaryKeySelective(tenant);
                userService.modify(oldPhone, newPhone);
            }else {
                if(tenant2.getId() .equals(tenant.getId()) ){
                    tenantMapper.updateByPrimaryKeySelective(tenant);
                    userService.modify(oldPhone, newPhone);
                }else{
                    throw new Exception("手机号"+newPhone+"已存在！");
                }
            }
        }
        return tenant;
    }

    /**
     * 删除
     *
     * @param id
     */
    @Override
    public void delById(Long id) throws Exception {
        Tenant tenant = new Tenant();
        Tenant saved = tenantMapper.selectByPrimaryKey(id);
        if (saved.getMainId() == null || saved.getMainId() <= 0)
            throw new Exception("主要联系人不能直接删除！");
        tenant.setId(id);
        tenant.setState(StatusCons.HISTORY);
        tenantMapper.updateByPrimaryKeySelective(tenant);
    }

    /**
     * 重置密码
     * @param id
     * @param employee
     * @return
     * @throws Exception
     */
    public CommonResponse resetPassword(Long id,Employee employee) throws Exception{
        try{
            Tenant tenant = tenantMapper.selectByPrimaryKey(id);
            String remark = tenant.getRemark();
            Date now  = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = formatter.format(now);
            remark += "   操作员["+employee.getName()+"],重置密码,时间["+dateString+"]。";
            Tenant updateT = new Tenant();
            updateT.setId(id);
            updateT.setPwd("123456");
            updateT.setRemark(remark);
            tenantMapper.updateByPrimaryKeySelective(updateT);
        }catch (Exception e){
            throw new CoreException("重置密码失败!");
        }
        return CommonResponse.buildAddSuccessResponse("重置密码!",null);
    }

    /**
     * 根据微信key获取租房信息
     *
     * @param phone
     * @return
     */
    @Override
    public Rent getTenantRent(String phone) {
        Tenant tenant = new Tenant();
        tenant.setPhone(phone);
        return tenantMapper.getTanantRent(tenant);
    }

    /**
     * 邀请好友
     * mainId
     *
     * @param tenant
     * @return
     */
    @Override
    @Transactional
    public Tenant addFriend(Tenant tenant) throws Exception {
        if (tenant.getMainId() == null || tenant.getMainId() <= 0)
            throw new Exception("请指定租房人！");
        if (Strings.isNullOrEmpty(tenant.getPhone()))
            throw new Exception("好友手机号码不能为空！");
        Tenant check = new Tenant();
        check.setPhone(tenant.getPhone());
        check.setState(StatusCons.VALID);
        check.setMainId(tenant.getMainId());
        check.setType(TenantTypeCons.FRIEND);
        List<Tenant> chenckTenantList = tenantMapper.select(check);
        if (chenckTenantList != null &&!chenckTenantList.isEmpty())
            throw new Exception("该好友已在好友列表中，请勿重复操作！");
        tenant.setState(StatusCons.VALID);
        tenant.setType(TenantTypeCons.FRIEND);
        tenantMapper.insert(tenant);
        userService.insert(tenant.getPhone(), AppUserType.FRIEND);
        //更新租房人好友数量
        Tenant query = new Tenant();
        query.setMainId(tenant.getMainId());
        query.setState(StatusCons.VALID);
        List<Tenant> tenantList = tenantMapper.select(query);
        Tenant mian = new Tenant();
        mian.setId(tenant.getMainId());
        mian.setFriendsSize(tenantList.size());
        tenantMapper.updateByPrimaryKeySelective(mian);
        //更新业务表租房人好友数量
        Rent rent = tenantMapper.getTanantRent(mian);
        if(rent==null)
            throw new  Exception("未找到有效的租房记录！");
        rent.setFriendsSize(tenantList.size());
        tenantMapper.updateTanantRent(rent);
        return tenant;
    }

    /**
     * 查询租列表
     *
     * @param request
     * @return
     */
    @Override
    public List<Map> getTenantList(PageRequest<TenantQuery> request) {
        PageUtil.start(request);
        return tenantMapper.getTenantList(request.getQuery());
    }

    /**
     * 查询3天未开门的租客信息
     *
     * @param request
     * @return
     */
    @Override
    public List<Map> getErrInfoList(PageRequest<TenantQuery> request) {
        PageUtil.start(request);
        return tenantMapper.getErrInfoList(request.getQuery());
    }
    /**
     * 设置主要承租人
     *
     * @param tenantId
     */
    @Override
    @Transactional
    public void setMainTenant(Long tenantId) throws Exception {
        Tenant tenant = tenantMapper.selectByPrimaryKey(tenantId);
        if (tenant == null)
            throw new Exception("租客记录不存在");
        Rent rent=tenantMapper.getTanantRent(tenant);
        rent.setTenantId(tenantId);
        rent.setTenantTel(tenant.getPhone());
        rent.setTenantName(tenant.getName());
        tenantMapper.updateTanantRent(rent);
        int friendSize = rent.getFriendsSize();
        Long mainId = tenant.getMainId();
        if (mainId != null && mainId > 0) {
            //存在主要承租人
            Tenant mainQuery = new Tenant();
            mainQuery.setMainId(mainId);
            mainQuery.setState(StatusCons.VALID);
            List<Tenant> tenants = tenantMapper.select(mainQuery);
            Tenant mainTenant = tenantMapper.selectByPrimaryKey(mainId);
            mainTenant.setMainId(tenantId);
            mainTenant.setFriendsSize(0);
            mainTenant.setType(TenantTypeCons.FRIEND);
            tenants.add(mainTenant);
            tenants.stream().forEach(t -> {
                if (!t.getId() .equals(tenantId) ) {
                    t.setMainId(tenantId);
                } else {
                    t.setType(TenantTypeCons.TENANT);
                    t.setMainId(0L);
                    t.setFriendsSize(friendSize);
                }
                tenantMapper.updateByPrimaryKeySelective(t);
            });
        }
    }

    @Value("${iot.url}")
    private String ioturl;
    @Value("${iot.sourceId}")
    private String sourceId;

    /**
     * 生成或者重置用户锁密码
     * @param tid
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    public CommonResponse resetLockpwd(Long tid)throws Exception{
        //保存密码
        Tenant t       = tenantMapper.selectByPrimaryKey(tid);
        int pwdCnt = t.getPwdCnt();
        DevLockPassword dd = new DevLockPassword();
        dd.setTenantId(t.getId());
        dd.setState(1);//有效
        int cnt= devLockPasswordMapper.selectCount(dd);
        if(pwdCnt<=cnt){
            throw new Exception("用户【"+t.getName()+"】,已存在"+cnt+"个密码,不能再新增密码");
        }
        String lockpwd = get6NumForLockPwd();
        //由用户==》拿lockid
        Long houseId = 0L;
        Rent rrent = null;
        try{
            Rent query = new Rent();
            query.setTenantId(tid);
            query.setState(1);
            List<Rent> rent = rentMapper.select(query);
            if(rent==null||rent.isEmpty()||rent.size()!=1){
                throw new Exception("没有找到有效的出租信息!");
            }
            rrent = rent.get(0);
            houseId = rrent.getHousesId();
        }catch (Exception e){
            throw e;
        }
        Long lockId = 0L;
        DevLock ddevLock = null;
        try{
            DevLock devLock = new DevLock();
            devLock.setHouseId(houseId);
            devLock.setState(1);
            List<DevLock> dl =devLockMapper.select(devLock);
            if(dl==null||dl.isEmpty()||dl.size()!=1){
                throw new Exception("没有找到有效的锁信息!");
            }
            ddevLock = dl.get(0);
            lockId = ddevLock.getId();
        }catch (Exception e){
            throw e;
        }
        //调用NB接口
        try{
            Map<String, String> params = new HashMap<String,String>();
            params.put("imei",ddevLock.getImei());
            params.put("userId",t.getId()+"");
            params.put("password",lockpwd);
            params.put("sourceId",sourceId);
            String  str = HttpClientUtils.postForm(ioturl+"lockpassword/add", params, null, 10000, 10000);

            JSONObject obj = JSON.parseObject(str);
            Integer status = obj.getInteger("status");
            if(status!=1){
                throw new Exception("IOT返回状态【"+status+"】错误!");
            }
        }catch (Exception e){
            throw new Exception("访问IOT接口出错:"+e.getMessage());
        }

        //新增锁密码
        DevLockPassword devLockPassword = new DevLockPassword();
        devLockPassword.setUpassword(lockpwd);
        devLockPassword.setAddTime(new Date());
        devLockPassword.setState(1);
        devLockPassword.setLockId(lockId+"");
        devLockPassword.setTenantId(tid);
        devLockPasswordMapper.insertSelective(devLockPassword);
        try {
            t.setPwd(lockpwd);
            //发送短信
            smsService.resetLockpwdSms(t);
        } catch (Exception e) {
            throw new Exception("发送租客短信失败,请查看短信服务是否正常!");
        }
        return CommonResponse.buildUpdateSuccessResponse("锁密码已生产成功，请用户及时查看短信!", null);
    }

    /**
     * 6位随机数字
     * @return
     */
    private String get6NumForLockPwd(){
        String       sources = "0123456789"; // 加上一些字母，就可以生成pc站的验证码了
        Random       rand    = new Random();
        StringBuffer flag    = new StringBuffer();
        for (int j = 0; j < 6; j++)
        {
            flag.append(sources.charAt(rand.nextInt(9)) + "");
        }
        return  flag.toString();
    }

    /**
     * 修改用户 密码数量、卡数量、指纹数量的配置
     * @param tenant
     * @return
     */
    public CommonResponse changeTenantSet(Tenant tenant)throws Exception{
        try {
            Tenant tenantUp = new Tenant();
            tenantUp.setId(tenant.getId());
            tenantUp.setCardCnt(tenant.getCardCnt());
            tenantUp.setPwdCnt(tenant.getPwdCnt());
            tenantUp.setFingerPintCnt(tenant.getFingerPintCnt());
            tenantMapper.updateByPrimaryKeySelective(tenantUp);
        } catch (Exception e) {
            throw new Exception("修改配置出错:"+e.getMessage());
        }
        return CommonResponse.buildUpdateSuccessResponse("修改成功!", null);
    }


    /**
     * 清除本月退租用户密码卡指纹，调用NB接口
     * @return
     * @throws Exception
     */
    @Override
    public CommonResponse clearPwdCardFg()throws Exception{
        log.info("清除本月退租用户密码卡指纹===》执行开始");
        //查询出符合条件的租客
        List<Map> list = tenantMapper.getTenantPwdCardFgList();
        log.info("===共有用户==>"+list.size());
        for(Map map :list){
            String pwdCnt = map.get("pwdCnt")+"";
            String cardCnt = map.get("cardCnt")+"";
            String fgCnt = map.get("fgCnt")+"";
            String tenantId = map.get("tenantId")+"";
            String tenantName = map.get("tenantName")+"";
            String houseNumb = map.get("houseNumb")+"";
            String imei = map.get("imei")+"";

            //参数
            Map<String, String> params = new HashMap<String,String>();
            params.put("imei",imei);
            params.put("userId",tenantId);
            params.put("sourceId",sourceId);
            //清除密码
            if(!Strings.isNullOrEmpty(pwdCnt)&&!"null".equalsIgnoreCase(pwdCnt)){
                try{
                    String  str = HttpClientUtils.postForm(ioturl+"lockpassword/clear", params, null, 10000, 10000);
                    JSONObject obj = JSON.parseObject(str);
                    Integer status = obj.getInteger("status");
                    if(status!=1){
                        throw new Exception("清除密码IOT返回状态【"+status+"】错误!");
                    }
                    //设置密码状态注销
                    DevLockPassword devLockPassword = new DevLockPassword();
                    devLockPassword.setState(0);//注销
                    Example example = new Example(DevLockPassword.class);
                    example.createCriteria().andEqualTo("tenantId",Long.parseLong(tenantId));
                    devLockPasswordMapper.updateByExampleSelective(devLockPassword,example);
                }catch (Exception e){
                    log.info("访问IOT接口出错:"+e.getMessage()+"  用户:"+tenantName+" 房号:"+houseNumb);
                }
            }
            //清除卡
            if(!Strings.isNullOrEmpty(cardCnt)&&!"null".equalsIgnoreCase(cardCnt)){
                try{
                    String  str = HttpClientUtils.postForm(ioturl+"iccard/clear", params, null, 10000, 10000);
                    JSONObject obj = JSON.parseObject(str);
                    Integer status = obj.getInteger("status");
                    if(status!=1){
                        throw new Exception("清除卡IOT返回状态【"+status+"】错误!");
                    }

                    //设置卡状态注销
                    DevLockCard devLockCard = new DevLockCard();
                    devLockCard.setState(0);//注销
                    Example example = new Example(DevLockCard.class);
                    example.createCriteria().andEqualTo("tenantId",Long.parseLong(tenantId));
                    devLockCardMapper.updateByExampleSelective(devLockCard,example);
                }catch (Exception e){
                    log.info("访问IOT接口出错:"+e.getMessage()+"  用户:"+tenantName+" 房号:"+houseNumb);
                }
            }
            //清除指纹
            if(!Strings.isNullOrEmpty(fgCnt)&&!"null".equalsIgnoreCase(fgCnt)){
                try{
                    String  str = HttpClientUtils.postForm(ioturl+"userfinger/clear", params, null, 10000, 10000);
                    JSONObject obj = JSON.parseObject(str);
                    Integer status = obj.getInteger("status");
                    if(status!=1){
                        throw new Exception("清除指纹IOT返回状态【"+status+"】错误!");
                    }
                    //设置指纹状态注销
                    DevLockFingerPrint devLockFingerPrint = new DevLockFingerPrint();
                    devLockFingerPrint.setState(0);//注销
                    Example example = new Example(DevLockFingerPrint.class);
                    example.createCriteria().andEqualTo("tenantId",Long.parseLong(tenantId));
                    devLockFingerprintMapper.updateByExampleSelective(devLockFingerPrint,example);
                }catch (Exception e){
                    log.info("访问IOT接口出错:"+e.getMessage()+"  用户:"+tenantName+" 房号:"+houseNumb);
                }
            }
        }
        log.info("清除本月退租用户密码卡指纹===》执行结束");
        return CommonResponse.buildDefaultSuccessResponse("清理成功",null);
    }
}
